<!DOCTYPE html>
<html lang="en">

<head>
    <title></title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="css/style.css" rel="stylesheet">
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        body {
            display: flex;
            justify-content: center;
            align-items: center;
            width: 100vw;
            height: 100vh;
        }

        dl {
            width: 400px;
            display: flex;
            flex-direction: column;
        }

        dt {
            background: #e67e22;
            border-bottom: solid 2px #333;
            height: 50px;
            display: flex;
            justify-content: center;
            align-items: center;
            cursor: pointer;
        }

        dd {
            height: 200px;
            background: #bdc3c7;
            font-size: 5em;
            text-align: center;
            line-height: 200px;
        }

        body {
            background-color: rgb(152, 155, 200);
        }
    </style>
</head>

<body>
    <!-- <dl>
        <dt>面板1</dt>
        <dd>1</dd>
        <dt>面板2</dt>
        <dd hidden="hidden">2</dd>
        <dt>面板3</dt>
        <dd hidden="hidden">3</dd>
        <dt>面板4</dt>
        <dd hidden="hidden">4</dd>
    </dl> -->
</body>
<script>
    // function aa() {
    //     console.log('我是aa');
    // }
    // aa();//这种形式  直接挂载到window原型中了  不能与window中的方法 重名 会出现覆盖
    // window.aa();
    // let aaa = function () {//这种方式 有作用于 不能挂载到 window对象中
    //     console.log('我是aa');
    // };
    // aaa();
    //默认参数的技巧
    // let sum = function (...arg) {
    //     return arg.reduce((a, b) => a + b);
    // };
    // console.log(sum(1, 5, 6, 54, 4, 9, 87, 8, 5));
    //利用 argments方法求和
    // function sum() {
    //     //获取实参个数
    //     let temp = 0;
    //     for (let i = 0; i < arguments.length; i++) {
    //         temp += arguments[i];
    //     }
    //     return temp;
    // }
    // console.log(sum(1, 5, 6, 5, 8, 94, 6, 4, 5, 6))
    //递归求阶乘
    // function dg(num = 3) {
    //     if (num == 1) return 1;
    //     return num * dg(num - 1);
    // }
    // console.log(dg(5));
    //递归求和
    // function dSum(...arg) {
    //     console.log(arg);
    //     if (arg.length == 0) return 0;
    //     return arg.pop() + dSum(...arg);
    // }
    // console.log(dSum(1, 5, 3, 6))
    //递归改变对象属性 在原有的js成绩中再加n
    // let obj = [
    //     { name: '张三', js: 55 },
    //     { name: '李四', js: 45 },
    //     { name: '王二', js: 68 },
    //     { name: '麻子', js: 78 },
    //     { name: '锅盔', js: 86 },
    // ];
    // //obj 修改的对象 n再加多少 i递归结束条件
    // function putObj(obj, n = 10, i = 0) {
    //     if (i == obj.length) return obj;
    //     obj[i].js += n;
    //     return putObj(obj, n, ++i);
    // }
    // console.table(putObj(obj, 20))
    //function 定义的方式 与 ()=>函数的方式 中的this指向问题
    // let obj = {
    //     name: '张三',
    //     show: () => {
    //         console.log(this);
    //         console.log(this.name);
    //     },
    //     show2: function () {
    //         console.log(this);
    //         console.log(this.name);
    //     }
    // };
    // obj.show();
    // obj.show2();
    //箭头函数中的this 指向的是window 而 function中的方法是指向obj对象

    // let lesson = {
    //     stie: '张三',
    //     lists: ['js', 'css', 'html'],
    //     //在每一门课程上添加姓名
    //     show() {
    //         console.log(this);//指当前对象
    //         return this.lists.map((item) => {
    //             return `${this.stie}-${item}`;//['张三-js', '张三-css', '张三-html']
    //         });
    //     },
    //     show2() {
    //         const _this = this;
    //         console.log(this);//指当前对象
    //         return this.lists.map(function (item) {
    //             console.log(_this);//this指向window
    //             return `${_this.stie}-${item}`;
    //         });
    //     }
    // };
    // console.log(lesson.show2());
    //有此例子可见 function 定义的函数 this指向window  而箭头函数定义的方法 this是指向上一级的this 区块链向上找的过程
    // var name = 'hdcms';
    // var obj = {
    //     name: '后盾人',
    //     getName: function () {
    //         var self = this;
    //         return function () {
    //             return this.name;
    //         };
    //     }
    // };
    // console.log(obj.getName()()); //返回window.name的值hdcms
    // var name = 'hdcms';
    // var obj = {
    //     name: '后盾人',
    //     getName: function () {
    //         var self = this;
    //         return () => {
    //             return this.name;
    //         };
    //     }
    // };
    // console.log(obj.getName()()); //返回window.name的值后盾人


    //call apply bind的用法
    //作用 改变 this 指针，也可以理解为对象借用方法，就现像生活中向邻居借东西一样的事情

    // function User(name) {
    //     this.name = name;
    // }
    // let hd = new User('樊哙');
    // //正常来说 hd.name = 樊哙 现在想改变 为 dd.name=刘邦 用 call
    // console.log(hd.name);//樊哙
    // let dd = {};
    // User.call(dd, '刘邦');
    // console.log(dd.name);//刘邦
    //构造函数中的this默认是一个空对象，然后构造函数处理后把这个空对象变得有值。
    //function 默认this=null 在执行是this=window 在没用改变的情况下
    //call 可以改变构造函数中的空对象，即让构造函数 this 指向到另一个对象。
    //call apply 的区别
    // function show(title) {
    //     alert(`${title + this.name}`);
    // }
    // let lisi = {
    //     name: '李四'
    // };
    // let wangwu = {
    //     name: '王五'
    // };
    // show.call(lisi, '韩信');
    // show.apply(wangwu, ['张良']);
    //call 与 apply 用于显示的设置函数的上下文，两个方法作用一样都是将对象绑定到 this，只是在传递参数上有所不同。
    //apply 用数组传参 call 需要分别传参
    //找数组中的数值最大值 用call apply
    // let arr = [5, 9, 87, 46, 55, 123];
    // console.log(Math.max.apply(Math, arr));
    // console.log(Math.max.call(Math, ...arr));
    // //折叠面板
    // function panel(i) {
    //     let dds = document.querySelectorAll('dd');
    //     dds.forEach(item => {
    //         item.setAttribute('hidden', 'hidden');
    //     });
    //     dds[i].removeAttribute('hidden');
    // }
    // document.querySelectorAll('dt').forEach((item, i) => {
    //     item.addEventListener('click', () => panel.call(null, i));
    // })
    //bind 的用法
    //实现随机生成色
    function colorRandom(num, _this) {
        let temp = [];
        for (let i = 0; i < num; i++)temp.push(Math.floor(Math.random() * 255 + 1));
        _this.style.backgroundColor = `rgb(${temp[0]},${temp[1]},${temp[2]})`;
        console.log(`rgb[${temp[0]},${temp[1]},${temp[2]}]`);
    }
    function Color(elem) {
        this.elem = elem;
        setInterval(() => {
            colorRandom(3, this.elem);
        }, 1000);
    }
    let obj = new Color(document.body);
</script>

</html>